#ifndef _MB_COM_H
#define _MB_COM_H

#include "mbdef.h"
#include "crc_ext.h"

#ifdef __cplusplus
extern "C"
{
#endif

	uint8_t mb_data_send(mb_obj_type *mb_obj, void (*send)(uint8_t), uint8_t len);

	uint8_t mb_data_send_u32_fifo(mb_obj_type *mb_obj, volatile uint32_t *pdat, uint8_t len);
	uint8_t mb_data_send_u16_fifo(mb_obj_type *mb_obj, volatile uint16_t *pdat, uint8_t len);
	uint8_t mb_data_send_u8_fifo(mb_obj_type *mb_obj, volatile uint8_t *pdat, uint8_t len);

	void mb_send_end(mb_obj_type *mb_obj);

	uint8_t mb_data_pre_rcv(mb_obj_type *mb_obj);

	void mb_data_rcv_directly(mb_obj_type *mb_obj, uint8_t dat);

	void mb_data_rcv(mb_obj_type *mb_obj, uint8_t dat);

	void mb_data_rcv_u32_fifo(mb_obj_type *mb_obj, volatile uint32_t *pdat, uint16_t len);
	void mb_data_rcv_u16_fifo(mb_obj_type *mb_obj, volatile uint16_t *pdat, uint16_t len);
	void mb_data_rcv_u8_fifo(mb_obj_type *mb_obj, volatile uint8_t *pdat, uint16_t len);

	uint8_t mb_tcp_rcv(mb_obj_type *mb_obj, uint8_t *dat, uint16_t len);

	void mb_rtu_timer_run(mb_obj_type *mb_obj); 
	
	void mb_timer_en(mb_obj_type *mb_obj); 
	void mb_timer_dis(mb_obj_type *mb_obj);
	void mb_exe_success(mb_obj_type *mb_obj);
	void mb_exe_fail(mb_obj_type *mb_obj);

	void mb_slave_id_set(mb_obj_type *mb_obj, uint8_t id);	   
	void mb_timeout_set(mb_obj_type *mb_obj, uint16_t time);   
	void mb_rtu_time_set(mb_obj_type *mb_obj, uint8_t time);  
	void mb_end_delay_set(mb_obj_type *mb_obj, uint8_t time); 
	void mb_id0_ack_set(mb_obj_type *mb_obj, char new_st);	   
	void mb_adu_cut_set(mb_obj_type *mb_obj, char new_st);	   

	void mb_obj_init(mb_obj_type *mb_obj); 

	void mb_poll(mb_obj_type *mb_obj);
	void smb_poll(mb_obj_type *mb_obj);
	void mmb_poll(mb_obj_type *mb_obj);

	void mmb_cmd_buff_init(mb_obj_type *mb_obj, mb_cmd_buff_type *pBuff, uint8_t mbCBuffSize, uint8_t mbSCBuffSize);

#if MB_MUL_TASK_EN > 0
	void mmb_cmd_mutex_init(mb_obj_type *mb_obj, void (*Pend)(void), void (*Post)(void));
#endif
	
	uint8_t mmb_os_stc_cmd_req(mb_obj_type *mb_obj, uint8_t CmdSite, mb_cmd_buff_type *cmd);
	
	uint8_t mmb_os_dyna_cmd_req(mb_obj_type *mb_obj, mb_cmd_buff_type *cmd);
	uint8_t mmb_os_stc_cmd_del(mb_obj_type *mb_obj, uint8_t CmdSite);

	uint8_t mmb_stc_cmd_req(mb_obj_type *mb_obj, uint8_t CmdSite, mb_cmd_buff_type *cmd);
	uint8_t mmb_dyna_cmd_req(mb_obj_type *mb_obj, mb_cmd_buff_type *cmd);
	uint8_t mmb_stc_cmd_del(mb_obj_type *mb_obj, uint8_t CmdSite);
	uint8_t mmb_cmd_ready_num(mb_obj_type *mb_obj);
	uint8_t mmb_cmd_idle_num(mb_obj_type *mb_obj);
	void mmb_cmd_clr(mb_obj_type *mb_obj);

	void mb_gus_key_opt(mb_gus_keep_key_t *key, uint16_t check_val_now, uint8_t b_pulse);
	void mb_package_send(mb_obj_type *mb_obj); 

#define mb_fun_api_make(name, obj)                                                 \
                                                                                   \
	static void name##_obj_init(void);                                             \
	static void name##_mb_poll(void);                                              \
	static uint8_t name##_stc_cmd_req(uint8_t CmdSite, mb_cmd_buff_type *pcmd);    \
	static uint8_t name##_dyna_cmd_req(mb_cmd_buff_type *pcmd);                    \
	static uint8_t name##_stc_cmd_del(uint8_t CmdSite);                            \
	static uint8_t name##_stc_cmd_os_req(uint8_t CmdSite, mb_cmd_buff_type *pcmd); \
	static uint8_t name##_dyna_cmd_os_req(mb_cmd_buff_type *pcmd);                 \
	static uint8_t name##_stc_cmd_os_del(uint8_t CmdSite);                         \
	static uint8_t name##_cmd_ready_num(void);                                     \
	static uint8_t name##_cmd_idle_num(void);                                      \
	static void name##_cmd_clr(void);                                              \
                                                                                   \
	static void name##_obj_init(void)                                              \
	{                                                                              \
		mb_obj_init(&obj);                                                         \
	}                                                                              \
	static void name##_mb_poll(void)                                               \
	{                                                                              \
		mb_poll(&obj);                                                             \
	}                                                                              \
	static uint8_t name##_stc_cmd_req(uint8_t CmdSite, mb_cmd_buff_type *pcmd)     \
	{                                                                              \
		return mmb_stc_cmd_req(&obj, CmdSite, pcmd);                               \
	}                                                                              \
	static uint8_t name##_dyna_cmd_req(mb_cmd_buff_type *pcmd)                     \
	{                                                                              \
		return mmb_dyna_cmd_req(&obj, pcmd);                                       \
	}                                                                              \
	static uint8_t name##_stc_cmd_del(uint8_t CmdSite)                             \
	{                                                                              \
		return mmb_stc_cmd_del(&obj, CmdSite);                                     \
	}                                                                              \
	static uint8_t name##_stc_cmd_os_req(uint8_t CmdSite, mb_cmd_buff_type *pcmd)  \
	{                                                                              \
		return mmb_os_stc_cmd_req(&obj, CmdSite, pcmd);                            \
	}                                                                              \
	static uint8_t name##_dyna_cmd_os_req(mb_cmd_buff_type *pcmd)                  \
	{                                                                              \
		return mmb_os_dyna_cmd_req(&obj, pcmd);                                    \
	}                                                                              \
	static uint8_t name##_stc_cmd_os_del(uint8_t CmdSite)                          \
	{                                                                              \
		return mmb_os_stc_cmd_del(&obj, CmdSite);                                  \
	}                                                                              \
	static uint8_t name##_cmd_ready_num(void)                                      \
	{                                                                              \
		return mmb_cmd_ready_num(&obj);                                            \
	}                                                                              \
	static uint8_t name##_cmd_idle_num(void)                                       \
	{                                                                              \
		return mmb_cmd_idle_num(&obj);                                             \
	}                                                                              \
	static void name##_cmd_clr(void)                                               \
	{                                                                              \
		mmb_cmd_clr(&obj);                                                         \
	}                                                                              \
	static const mb_fun_interface_type name##_api = {                              \
		name##_obj_init,                                                           \
		name##_mb_poll,                                                            \
		name##_stc_cmd_os_req,                                                     \
		name##_dyna_cmd_os_req,                                                    \
		name##_stc_cmd_os_del,                                                     \
		name##_stc_cmd_req,                                                        \
		name##_dyna_cmd_req,                                                       \
		name##_stc_cmd_del,                                                        \
		name##_cmd_ready_num,                                                      \
		name##_cmd_idle_num,                                                       \
		name##_cmd_clr,                                                            \
	}

#define mb_api_ref(name) extern const mb_fun_interface_type name##_api
#define mb_api_name(name) &name##_api
#define mb_api_link(name, obj) obj.api = &name##_api

#ifdef __cplusplus
}
#endif

#endif
